package com.mall.project.sys.controller;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.mall.common.core.asserts.ApiAssert;
import com.mall.common.core.cons.StatusCons;
import com.mall.common.core.enums.ErrorCodeEnum;
import com.mall.common.core.model.response.ApiResponses;
import com.mall.common.core.model.supers.SuperController;
import com.mall.common.core.utils.TreeUtils;
import com.mall.common.security.annotation.PreAuth;
import com.mall.project.sys.model.dto.DeptDTO;
import com.mall.project.sys.model.dto.DeptTreeDTO;
import com.mall.project.sys.model.entity.Dept;
import com.mall.project.sys.model.entity.User;
import com.mall.project.sys.model.parm.DeptPARM;
import com.mall.project.sys.service.IDeptService;
import com.mall.project.sys.service.IUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 部门表 前端控制器
 * </p>
 *
 * @author Sam
 * @since 2021-04-13
 */
@Api(tags = {"部门"})
@RestController
@RequestMapping("/dept")
public class DeptRestController extends SuperController {

    @Autowired
    private IDeptService deptService;
    @Autowired
    private IUserService userService;

    @PreAuth
    @ApiOperation("获取所有部门 返回树")
    @GetMapping("/trees")
    public ApiResponses<List<DeptTreeDTO>> treeList(@RequestParam(value = "status", required = false) Integer status) {
        List<DeptTreeDTO> treeSource = deptService.list(Wrappers.<Dept>lambdaQuery()
                .eq(Objects.nonNull(status), Dept::getStatus, status)
                .orderByAsc(Dept::getOrderNum))
                .stream().map(e -> e.convert(DeptTreeDTO.class)).collect(Collectors.toList());
        List<DeptTreeDTO> treeList = treeSource.stream().filter(e -> !(Objects.nonNull(e.getPid()) && !"0".equals(e.getPid())))
                .map(e -> TreeUtils.findChildren(e, treeSource)).collect(Collectors.toList());
        return success(treeList);
    }

    @PreAuth
    @ApiOperation(value = "获取所有部门", response = DeptDTO.class)
    @GetMapping("/list")
    public ApiResponses<List<DeptDTO>> list(@RequestParam(value = "status", required = false) Integer status) {
        List<Dept> DeptList = deptService.list(Wrappers.<Dept>lambdaQuery()
                .eq(Objects.nonNull(status), Dept::getStatus, status)
                .orderByAsc(Dept::getOrderNum));
        List<DeptDTO> treeDTOS = DeptList.stream().map(e -> e.convert(DeptDTO.class)).collect(Collectors.toList());
        return success(treeDTOS);
    }

    @PreAuth
    @ApiOperation("单条查询部门")
    @GetMapping("/{id}")
    public ApiResponses<Dept> getById(@PathVariable("id") String id) {
        Dept dept = deptService.getById(id);
        return success(dept);
    }

    @PreAuth
    @ApiOperation("新增部门")
    @PostMapping
    public ApiResponses<Void> create(@RequestBody @Validated(value = DeptPARM.Create.class) DeptPARM deptPARM) {
        Dept dept = deptPARM.convert(Dept.class);
        ApiAssert.isTrue(ErrorCodeEnum.BAD_ADD_FAILURE, deptService.save(dept));
        return success();
    }

    @PreAuth
    @ApiOperation("修改部门")
    @PutMapping("/{id}")
    public ApiResponses<Void> updateById(@PathVariable("id") String id, @RequestBody DeptPARM deptPARM) {
        ApiAssert.isFalse(ErrorCodeEnum.INTERNAL_SERVER_ERROR.convert("上级部门不能是自己"),
                Objects.equals(id, deptPARM.getPid()));
        ApiAssert.isFalse(ErrorCodeEnum.INTERNAL_SERVER_ERROR.convert("该部门包含未作废的子部门"),
                Objects.equals(StatusCons.DISABLE, deptPARM.getStatus()) &&
                        deptService.count(Wrappers.<Dept>lambdaQuery()
                                .eq(Dept::getPid, id).eq(Dept::getStatus, StatusCons.NORMAL)) > 0);
        deptPARM.setId(id);
        Dept updateDept = deptPARM.convert(Dept.class);
        ApiAssert.isTrue(ErrorCodeEnum.BAD_UPDATE_FAILURE, deptService.updateById(updateDept));
        return success();
    }

    @PreAuth
    @ApiOperation("删除部门")
    @DeleteMapping("/{id}")
    public ApiResponses<Void> deleteById(@PathVariable("id") String id) {
        Dept dept = deptService.getById(id);
        ApiAssert.notNull(ErrorCodeEnum.INTERNAL_SERVER_ERROR.convert("不存在此部门"), dept);
        int count = deptService.count(Wrappers.<Dept>lambdaQuery()
                .eq(Dept::getPid, id).eq(Dept::getStatus, StatusCons.NORMAL));
        ApiAssert.isFalse(ErrorCodeEnum.INTERNAL_SERVER_ERROR.convert("存在下级部门,不允许删除"), count > 0);
        int userDept = userService.count(Wrappers.<User>lambdaQuery().eq(User::getDeptId, id));
        ApiAssert.isFalse(ErrorCodeEnum.INTERNAL_SERVER_ERROR.convert("该部门存在绑定用户,不允许删除"), userDept > 0);
        //修改部门状态
        ApiAssert.isTrue(ErrorCodeEnum.BAD_DELETE_FAILURE, deptService.update(Wrappers.<Dept>lambdaUpdate()
                .set(Dept::getStatus, StatusCons.DISABLE).eq(Dept::getId, id)));
        return success();
    }
}

